{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模型评估"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 分类模型评估"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ROC、AUC绘制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.preprocessing import MinMaxScaler,StandardScaler\n",
    "from sklearn.preprocessing import LabelEncoder,OneHotEncoder\n",
    "from sklearn.preprocessing import Normalizer\n",
    "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n",
    "from sklearn.decomposition import PCA\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(       satisfaction_level  last_evaluation  number_project  \\\n",
       " 0                0.318681         0.265625             0.0   \n",
       " 1                0.780220         0.781250             0.6   \n",
       " 2                0.021978         0.812500             1.0   \n",
       " 3                0.692308         0.796875             0.6   \n",
       " 4                0.307692         0.250000             0.0   \n",
       " ...                   ...              ...             ...   \n",
       " 14994            0.340659         0.328125             0.0   \n",
       " 14995            0.307692         0.187500             0.0   \n",
       " 14996            0.307692         0.265625             0.0   \n",
       " 14997            0.021978         0.937500             0.8   \n",
       " 14998            0.307692         0.250000             0.0   \n",
       " \n",
       "        average_monthly_hours  time_spend_company  Work_accident  \\\n",
       " 0                   0.285047               0.125            0.0   \n",
       " 1                   0.775701               0.500            0.0   \n",
       " 2                   0.822430               0.250            0.0   \n",
       " 3                   0.593458               0.375            0.0   \n",
       " 4                   0.294393               0.125            0.0   \n",
       " ...                      ...                 ...            ...   \n",
       " 14994               0.257009               0.125            0.0   \n",
       " 14995               0.299065               0.125            0.0   \n",
       " 14996               0.219626               0.125            0.0   \n",
       " 14997               0.859813               0.250            0.0   \n",
       " 14998               0.289720               0.125            0.0   \n",
       " \n",
       "        promotion_last_5years  department  salary  \n",
       " 0                        0.0    0.777778     0.0  \n",
       " 1                        0.0    0.777778     0.5  \n",
       " 2                        0.0    0.777778     0.5  \n",
       " 3                        0.0    0.777778     0.0  \n",
       " 4                        0.0    0.777778     0.0  \n",
       " ...                      ...         ...     ...  \n",
       " 14994                    0.0    0.888889     0.0  \n",
       " 14995                    0.0    0.888889     0.0  \n",
       " 14996                    0.0    0.888889     0.0  \n",
       " 14997                    0.0    0.888889     0.0  \n",
       " 14998                    0.0    0.888889     0.0  \n",
       " \n",
       " [14999 rows x 9 columns], 0        1\n",
       " 1        1\n",
       " 2        1\n",
       " 3        1\n",
       " 4        1\n",
       "         ..\n",
       " 14994    1\n",
       " 14995    1\n",
       " 14996    1\n",
       " 14997    1\n",
       " 14998    1\n",
       " Name: left, Length: 14999, dtype: int64)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 总的预处理函数\n",
    "def hr_preprocessing(sl=False,le=False,npr=False,amh=False,tsc=False,wa=False,pl5=False,slr=False,dp=False,lower_d=False,ld_n=1):\n",
    "    # 读数据\n",
    "    df = pd.read_csv('./data/HR.csv')\n",
    "    # 1.清洗数据\n",
    "    df = df.dropna(subset=['satisfaction_level'])\n",
    "    df = df[df['last_evaluation']<=1][df['salary']!='nme']\n",
    "    # 2.得到标注\n",
    "    label = df['left']\n",
    "    df = df.drop('left',axis=1)\n",
    "    # 3.特征选择，特征较少，先不删除特征\n",
    "    # 4.特征处理\n",
    "    # 连续属性\n",
    "    scaler_lst = [sl,le,npr,amh,tsc,wa,pl5]\n",
    "    column_lst = ['satisfaction_level','last_evaluation','number_project','average_monthly_hours',\n",
    "                 'time_spend_company','Work_accident','promotion_last_5years']\n",
    "    for i in range(len(scaler_lst)):\n",
    "        if not scaler_lst[i]:\n",
    "            df[column_lst[i]] = MinMaxScaler().fit_transform(df[column_lst[i]].values.reshape(-1,1))\n",
    "        else:\n",
    "            df[column_lst[i]] = StandardScaler().fit_transform(df[column_lst[i]].values.reshape(-1,1))\n",
    "    # 离散属性\n",
    "    # 数值化重写map函数，把salary对应到我们想要的数值\n",
    "    def map_salary(s):\n",
    "        d = dict([('low',0),('medium',1),('high',2)])\n",
    "        return d.get(s,0)\n",
    "    scaler_lst = [slr,dp]\n",
    "    column_lst = ['salary','department']\n",
    "    for i in range(len(scaler_lst)):\n",
    "        if not scaler_lst[i]:\n",
    "            if column_lst[i] == 'salary':\n",
    "                df[column_lst[i]] = [map_salary(s) for s in df['salary'].values]\n",
    "            else:\n",
    "                df[column_lst[i]] = LabelEncoder().fit_transform(df[column_lst[i]])\n",
    "            # 归一化处理\n",
    "            df[column_lst[i]] = MinMaxScaler().fit_transform(df[column_lst[i]].values.reshape(-1, 1))\n",
    "        else:\n",
    "            df = pd.get_dummies(df,columns=[column_lst[i]])\n",
    "    # 5.降维\n",
    "    if lower_d:\n",
    "        # 因为标注只有两类，LDA降维只剩1类，所以不使用LDA，使用PCA\n",
    "        # return LinearDiscriminantAnalysis(n_components=ld_n)\n",
    "        return PCA(n_components=ld_n).fit_transform(df.values),label\n",
    "    return df,label\n",
    "\n",
    "features,label = hr_preprocessing()\n",
    "features,label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8999 3000 3000\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(array([[0.3956044 , 0.5       , 0.4       , ..., 0.        , 0.77777778,\n",
       "         0.        ],\n",
       "        [0.63736264, 0.734375  , 0.2       , ..., 0.        , 0.55555556,\n",
       "         0.5       ],\n",
       "        [0.68131868, 0.84375   , 0.2       , ..., 0.        , 0.66666667,\n",
       "         0.        ],\n",
       "        ...,\n",
       "        [0.34065934, 0.3125    , 0.        , ..., 0.        , 0.88888889,\n",
       "         0.        ],\n",
       "        [0.28571429, 0.984375  , 0.2       , ..., 0.        , 0.77777778,\n",
       "         0.5       ],\n",
       "        [0.69230769, 0.75      , 0.6       , ..., 0.        , 1.        ,\n",
       "         0.5       ]]),\n",
       " array([1, 0, 0, ..., 1, 1, 1], dtype=int64),\n",
       " array([[0.65934066, 0.3125    , 0.2       , ..., 0.        , 0.88888889,\n",
       "         0.5       ],\n",
       "        [0.95604396, 0.359375  , 0.2       , ..., 0.        , 0.22222222,\n",
       "         1.        ],\n",
       "        [0.43956044, 0.453125  , 0.4       , ..., 0.        , 0.77777778,\n",
       "         0.5       ],\n",
       "        ...,\n",
       "        [0.45054945, 0.34375   , 0.4       , ..., 0.        , 0.77777778,\n",
       "         0.        ],\n",
       "        [0.56043956, 0.5       , 0.4       , ..., 0.        , 0.11111111,\n",
       "         0.        ],\n",
       "        [0.84615385, 0.421875  , 0.2       , ..., 0.        , 0.77777778,\n",
       "         0.        ]]),\n",
       " array([0, 0, 0, ..., 0, 0, 0], dtype=int64),\n",
       " array([[0.38461538, 0.21875   , 0.        , ..., 0.        , 0.22222222,\n",
       "         0.5       ],\n",
       "        [0.86813187, 0.421875  , 0.2       , ..., 0.        , 0.11111111,\n",
       "         0.        ],\n",
       "        [0.83516484, 0.84375   , 0.        , ..., 0.        , 0.77777778,\n",
       "         0.5       ],\n",
       "        ...,\n",
       "        [0.52747253, 0.859375  , 0.4       , ..., 0.        , 0.77777778,\n",
       "         0.5       ],\n",
       "        [0.71428571, 1.        , 0.6       , ..., 0.        , 0.88888889,\n",
       "         0.5       ],\n",
       "        [0.91208791, 0.4375    , 0.        , ..., 0.        , 0.66666667,\n",
       "         0.        ]]),\n",
       " array([1, 0, 1, ..., 0, 1, 0], dtype=int64))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def hr_modeling(features,label):\n",
    "    f_v = features.values\n",
    "    l_v = label.values\n",
    "    f_names = features.columns.values\n",
    "    # 切分数据集，6:2:2\n",
    "    X_tt,X_validation,Y_tt,Y_validation = train_test_split(f_v,l_v,test_size=0.2)\n",
    "    X_train,X_test,Y_train,Y_test = train_test_split(X_tt,Y_tt,test_size=0.25)\n",
    "    print(len(X_train),len(X_validation),len(X_test))\n",
    "    return X_train,Y_train,X_test,Y_test,X_validation,Y_validation,f_names,f_v,l_v\n",
    "\n",
    "X_train,Y_train,X_test,Y_test,X_validation,Y_validation,f_names,f_v,l_v = hr_modeling(features,label)\n",
    "X_train,Y_train,X_test,Y_test,X_validation,Y_validation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "8999/8999 [==============================] - 0s 18us/step - loss: 0.3236\n",
      "Epoch 2/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.2723\n",
      "Epoch 3/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.2322\n",
      "Epoch 4/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.2055\n",
      "Epoch 5/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1901\n",
      "Epoch 6/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1828\n",
      "Epoch 7/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1797\n",
      "Epoch 8/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1790\n",
      "Epoch 9/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1789\n",
      "Epoch 10/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1789\n",
      "Epoch 11/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1789\n",
      "Epoch 12/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1787\n",
      "Epoch 13/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1785\n",
      "Epoch 14/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1782\n",
      "Epoch 15/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1780\n",
      "Epoch 16/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1777\n",
      "Epoch 17/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1774\n",
      "Epoch 18/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1773\n",
      "Epoch 19/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1770\n",
      "Epoch 20/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1768\n",
      "Epoch 21/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1766\n",
      "Epoch 22/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1764\n",
      "Epoch 23/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1762\n",
      "Epoch 24/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1760\n",
      "Epoch 25/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1758\n",
      "Epoch 26/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1755\n",
      "Epoch 27/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1753\n",
      "Epoch 28/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1751\n",
      "Epoch 29/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1748\n",
      "Epoch 30/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1746\n",
      "Epoch 31/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1744\n",
      "Epoch 32/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1741\n",
      "Epoch 33/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1739\n",
      "Epoch 34/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1736\n",
      "Epoch 35/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1734\n",
      "Epoch 36/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1731\n",
      "Epoch 37/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1729\n",
      "Epoch 38/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1726\n",
      "Epoch 39/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1724\n",
      "Epoch 40/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1721\n",
      "Epoch 41/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1719\n",
      "Epoch 42/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1716\n",
      "Epoch 43/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1713\n",
      "Epoch 44/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1711\n",
      "Epoch 45/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1708\n",
      "Epoch 46/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1705\n",
      "Epoch 47/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1703\n",
      "Epoch 48/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1700\n",
      "Epoch 49/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1697\n",
      "Epoch 50/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1694\n",
      "Epoch 51/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1692\n",
      "Epoch 52/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1689\n",
      "Epoch 53/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1686\n",
      "Epoch 54/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1683\n",
      "Epoch 55/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1680\n",
      "Epoch 56/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1677\n",
      "Epoch 57/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1675\n",
      "Epoch 58/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1672\n",
      "Epoch 59/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1669\n",
      "Epoch 60/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1666\n",
      "Epoch 61/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1663\n",
      "Epoch 62/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1660\n",
      "Epoch 63/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1657\n",
      "Epoch 64/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1654\n",
      "Epoch 65/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1651\n",
      "Epoch 66/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1648\n",
      "Epoch 67/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1645\n",
      "Epoch 68/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1642\n",
      "Epoch 69/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1640\n",
      "Epoch 70/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1637\n",
      "Epoch 71/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1634\n",
      "Epoch 72/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1631\n",
      "Epoch 73/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1628\n",
      "Epoch 74/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1625\n",
      "Epoch 75/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1622\n",
      "Epoch 76/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1619\n",
      "Epoch 77/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1616\n",
      "Epoch 78/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1613\n",
      "Epoch 79/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1610\n",
      "Epoch 80/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1607\n",
      "Epoch 81/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1604\n",
      "Epoch 82/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1601\n",
      "Epoch 83/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1598\n",
      "Epoch 84/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1595\n",
      "Epoch 85/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1592\n",
      "Epoch 86/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1589\n",
      "Epoch 87/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1586\n",
      "Epoch 88/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1583\n",
      "Epoch 89/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1580\n",
      "Epoch 90/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1577\n",
      "Epoch 91/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1574\n",
      "Epoch 92/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1572\n",
      "Epoch 93/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1569\n",
      "Epoch 94/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1566\n",
      "Epoch 95/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1563\n",
      "Epoch 96/100\n",
      "8999/8999 [==============================] - 0s 2us/step - loss: 0.1560\n",
      "Epoch 97/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1558\n",
      "Epoch 98/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1555\n",
      "Epoch 99/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1552\n",
      "Epoch 100/100\n",
      "8999/8999 [==============================] - 0s 3us/step - loss: 0.1550\n",
      "[[0.80869    0.19131   ]\n",
      " [0.8896879  0.1103121 ]\n",
      " [0.8610419  0.1389581 ]\n",
      " ...\n",
      " [0.69968253 0.30031747]\n",
      " [0.6712824  0.32871762]\n",
      " [0.71368915 0.28631088]]\n",
      "NN-AUC 0.7898700024527839\n",
      "NN-AUC_Score 0.7898700024527839\n",
      "[[0.77355754 0.22644246]\n",
      " [0.88096964 0.11903033]\n",
      " [0.8283829  0.17161709]\n",
      " ...\n",
      " [0.58839196 0.41160804]\n",
      " [0.7131803  0.2868197 ]\n",
      " [0.7405383  0.25946173]]\n",
      "NN-AUC 0.7645523044331072\n",
      "NN-AUC_Score 0.7645523044331072\n",
      "[[0.7962138  0.20378616]\n",
      " [0.9371718  0.06282818]\n",
      " [0.6499219  0.35007808]\n",
      " ...\n",
      " [0.7175731  0.28242695]\n",
      " [0.8551218  0.14487818]\n",
      " [0.77280504 0.22719492]]\n",
      "NN-AUC 0.7818981410354893\n",
      "NN-AUC_Score 0.7818981410354893\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.metrics import roc_curve,roc_auc_score,auc\n",
    "from keras.models import Sequential\n",
    "from keras.layers.core import Dense,Activation\n",
    "from keras.optimizers import SGD\n",
    "\n",
    "mdl = Sequential()\n",
    "mdl.add(Dense(50,input_dim=len(f_v[0])))\n",
    "mdl.add(Activation('sigmoid'))\n",
    "mdl.add(Dense(2))\n",
    "mdl.add(Activation('softmax'))\n",
    "sgd = SGD(lr=0.1)\n",
    "mdl.compile(loss='mse',optimizer='adam')\n",
    "mdl.fit(X_train,np.array([[0,1] if i==1 else [1,0] for i in Y_train]),epochs=100,batch_size=2048)\n",
    "\n",
    "xy_test = [(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]\n",
    "f = plt.figure()\n",
    "for i in range(len(xy_test)):\n",
    "    X_part = xy_test[i][0]\n",
    "    Y_part = xy_test[i][1]\n",
    "    Y_pred = mdl.predict(X_part)\n",
    "    print(Y_pred)\n",
    "    Y_pred = np.array(Y_pred[:,1]).reshape((1,-1))[0]\n",
    "#     print(i)\n",
    "#     print(\"NN-ACC:\",accuracy_score(Y_part,Y_pred))\n",
    "#     print(\"NN-REC:\",recall_score(Y_part,Y_pred))\n",
    "#     print(\"NN-F1:\",f1_score(Y_part,Y_pred))\n",
    "    f.add_subplot(1,3,i+1)\n",
    "    fpr,tpr,threshold = roc_curve(Y_part,Y_pred)\n",
    "    plt.plot(fpr,tpr)\n",
    "    print('NN-AUC',auc(fpr,tpr))\n",
    "    print('NN-AUC_Score',roc_auc_score(Y_part,Y_pred))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 回归模型评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LinearRegression\n",
      "Coef: [0.27268022 0.26917309]\n",
      "MSE: 0.05953800649100494\n",
      "MAE: 0.20434265775584715\n",
      "R2: 0.16759936150494903\n",
      "Ridge\n",
      "Coef: [0.27265976 0.26914916]\n",
      "MSE: 0.05953800657114579\n",
      "MAE: 0.20434390268155303\n",
      "R2: 0.16759936038450018\n",
      "Lasso\n",
      "Coef: [0.25039551 0.24227119]\n",
      "MSE: 0.0596363767370062\n",
      "MAE: 0.20586454360489492\n",
      "R2: 0.16622404747604003\n"
     ]
    }
   ],
   "source": [
    "# 引入线性回归，岭回归，lasso回归\n",
    "from sklearn.linear_model import LinearRegression,Ridge,Lasso\n",
    "from sklearn.metrics import mean_squared_error,mean_absolute_error,r2_score\n",
    "\n",
    "def regr_test(features,label):\n",
    "#     print('X',features)\n",
    "#     print('Y',label)\n",
    "    regr = LinearRegression()\n",
    "    regr.fit(features.values,label.values)\n",
    "    Y_pred = regr.predict(features.values)\n",
    "    print('LinearRegression')\n",
    "    print('Coef:',regr.coef_)\n",
    "    print('MSE:',mean_squared_error(label.values,Y_pred))\n",
    "    print('MAE:',mean_absolute_error(label.values,Y_pred))\n",
    "    print('R2:',r2_score(label.values,Y_pred))\n",
    "    regr = Ridge(alpha=0.1)\n",
    "    regr.fit(features.values,label.values)\n",
    "    Y_pred = regr.predict(features.values)\n",
    "    print('Ridge')\n",
    "    print('Coef:',regr.coef_)\n",
    "    print('MSE:',mean_squared_error(label.values,Y_pred))\n",
    "    print('MAE:',mean_absolute_error(label.values,Y_pred))\n",
    "    print('R2:',r2_score(label.values,Y_pred))\n",
    "    regr = Lasso(alpha=0.002)\n",
    "    regr.fit(features.values,label.values)\n",
    "    Y_pred = regr.predict(features.values)\n",
    "    print('Lasso')\n",
    "    print('Coef:',regr.coef_)\n",
    "    print('MSE:',mean_squared_error(label.values,Y_pred))\n",
    "    print('MAE:',mean_absolute_error(label.values,Y_pred))\n",
    "    print('R2:',r2_score(label.values,Y_pred))\n",
    "\n",
    "regr_test(features[['number_project','average_monthly_hours']],features['last_evaluation'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 聚类模型评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 轮廓系数\n",
    "from sklearn.metrics import silhouette_score\n",
    "from sklearn.datasets import make_circles,make_blobs,make_moons\n",
    "from sklearn.cluster import KMeans,DBSCAN,AgglomerativeClustering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kmeans 0 0.3774218566346258\n",
      "Kmeans 1 0.41641107390614296\n",
      "Kmeans 2 0.8043604863787004\n",
      "Kmeans 3 0.4589766003328164\n",
      "DBSCAN 0 0.10065244533240518\n",
      "DBSCAN 1 0.3118931624407566\n",
      "DBSCAN 2 0.8043604863787004\n",
      "Agglomerative 0 0.36101706850376436\n",
      "Agglomerative 1 0.4191851756163384\n",
      "Agglomerative 2 0.8043604863787004\n",
      "Agglomerative 3 0.3989969653254197\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 生成数据\n",
    "n_samples = 100\n",
    "circles = make_circles(n_samples=n_samples,factor=0.5,noise=0.05)\n",
    "moons = make_moons(n_samples=n_samples,noise=0.05)\n",
    "blobs = make_blobs(n_samples=n_samples,random_state=8,center_box=(-1,1),cluster_std=0.1)\n",
    "random_data = np.random.rand(n_samples,2),None\n",
    "\n",
    "# 引入模型\n",
    "colors = 'bgrcmyk'\n",
    "data = [circles,moons,blobs,random_data]\n",
    "models = [('None',None),\n",
    "         ('Kmeans',KMeans(n_clusters=3)),\n",
    "         ('DBSCAN',DBSCAN(min_samples=3,eps=0.3)),\n",
    "         ('Agglomerative',AgglomerativeClustering(n_clusters=3,linkage='ward'))]\n",
    "\n",
    "# 进行聚类并画图\n",
    "def cluster_show():\n",
    "    f = plt.figure()\n",
    "    for inx,clt in enumerate(models):\n",
    "        clt_name,clt_entity = clt\n",
    "        for i,dataset in enumerate(data):\n",
    "            X,Y = dataset\n",
    "            if not clt_entity:\n",
    "                clt_res = [0 for item in range(len(X))]\n",
    "            else:\n",
    "                clt_entity.fit(X)\n",
    "                clt_res = clt_entity.labels_.astype(np.int)\n",
    "            f.add_subplot(len(models),len(data),inx*len(data)+i+1)\n",
    "            plt.title(clt_name)\n",
    "            try:\n",
    "                print(clt_name,i,silhouette_score(X,clt_res))\n",
    "            except:\n",
    "                pass\n",
    "            [plt.scatter(X[p,0],X[p,1],color=colors[clt_res[p]]) for p in range(len(X))]\n",
    "    plt.show()\n",
    "\n",
    "cluster_show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
